560. 和为 K 的子数组
560. 和为 K 的子数组
func subarraySum(nums []int, k int) int {
    cntMap := make(map[int]int, len(nums))
    cntMap[0] = 1
    currentSum := 0
    ans := 0
    for _, num := range nums {
        currentSum+=num
        if val, ok := cntMap[currentSum-k]; ok {
            ans+=val
        }
        cntMap[currentSum]++
    }
    return ans
}
刚开始一直看不懂 currentSum-k 什么意思,后来问了下chatgpt。看下原话:
Note
这段代码的目的是检查当前的前缀和减去目标值 k 是否存在于哈希表 sumCount 中,从而帮助我们找到和为 k 的子数组。我们来详细解析一下:
- 
前缀和的概念:
- 前缀和是指数组中从第一个元素到当前元素的和。例如,对于数组 
[1, 2, 3],其前缀和为:- 累计到第一个元素:
1 - 累计到第二个元素:
1 + 2 = 3 - 累计到第三个元素:
1 + 2 + 3 = 6 
 - 累计到第一个元素:
 - 在代码中,
currentSum表示当前遍历到某个元素时的前缀和。 
 - 前缀和是指数组中从第一个元素到当前元素的和。例如,对于数组 
 - 
为什么要检查
currentSum - k:- 
如果当前前缀和是
currentSum,我们希望找到一个子数组,使得这个子数组的和为k。 - 
设这个子数组的起始位置为
j,那么可以得出:其中
i是当前元素的索引。 - 
通过变形可以得到:
 
- 这意味着,如果我们能找到某个位置的前缀和等于 
currentSum - k,那么从j到i的子数组的和就是k。 
 - 
 - 
哈希表的作用:
- 哈希表 
sumCount记录了每个前缀和出现的次数。 - 当我们检查 
currentSum - k是否存在于哈希表中时,如果存在,说明从某个之前的位置到当前的位置形成的子数组的和正好是k。 val是sumCount[currentSum-k]的值,表示前缀和为currentSum - k的次数,即表示有多少个以该前缀和为起点的子数组的和为k。
 - 哈希表 
 - 
计数更新:
- 如果找到了 
val,就说明当前前缀和之前有val个起点可以形成和为k的子数组,因此我们把count增加val。 
 - 如果找到了 
 
总之,这段代码的核心思想是利用前缀和的特性,通过检查哈希表来高效地找到和为 k 的子数组。如果有任何具体的疑问,欢迎继续提问!
关键点是这里:
如果当前前缀和是
currentSum,我们希望找到一个子数组,使得这个子数组的和为k。
设这个子数组的起始位置为j
遍历到i时,求以i结尾的子数组的和有哪些是k
这个解释相当清晰,写代码也就几分钟就写完了
前缀和如何求可以看: leetcode-303. 区域和检索 - 数组不可变